package models;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.OneToMany;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import play.Logger;
import play.db.jpa.Model;
import client.dtos.RevisionDTO;

@Entity
public class Revision extends Model {
	
	public long revision;
	
	public Date revisionDate;
	
	public String revisionMessage;
	
	public String revisionUser;
	
	@OneToMany
	public Set<RepositoryFile> affectedFiles;

	public static List<Revision> getRevisionsForFile(long repositoryFileID, int page) {
		Logger.info("************Finding repository with id " + repositoryFileID);
		final Session session = (Session)em().getDelegate();
		return (List<Revision>)session.createSQLQuery("select r.* from filerevision fr inner join revision r on fr.revision_id = r.id where repositoryfile_id = :fileId order by r.revision desc")
			   .addEntity(Revision.class)
			   .setParameter("fileId", repositoryFileID)
			   .setFirstResult(page*50)
			   .setMaxResults(50)
			   .list();
	}

	public static RevisionDTO convertToDTO(Revision revision) {
		final DateFormat df = DateFormat.getDateTimeInstance();
		if (revision==null) {
			throw new NullPointerException("Revision is null");
		}
		final RevisionDTO rDTO = new RevisionDTO();
		rDTO.setRevision(revision.revision);
		rDTO.setRevisionDate(revision.revisionDate);
		rDTO.setRevisionMessage(revision.revisionMessage);
		rDTO.setRevisionUser(revision.revisionUser);
		rDTO.setRevisionDateAsString(df.format(revision.revisionDate));
		return rDTO;
	}

	public static List<Revision> findByComment(String searchTerm) {
		final Session session = (Session)em().getDelegate();
		final Criteria criteria = session.createCriteria(Revision.class);
		return criteria.add(Restrictions.ilike("revisionMessage", searchTerm, MatchMode.ANYWHERE))
					   .addOrder(Order.desc("revisionDate")).list();
	}

	public static List<RevisionDTO> convertToDTOs(List<Revision> revisions) {
		final List<RevisionDTO> returnList = new ArrayList(revisions.size());
		for (final Revision r : revisions) {
			returnList.add(convertToDTO(r));
		}
		return returnList;
	}
	
}
